package com.sz.admin.system.service.impl;

import com.sz.admin.system.pojo.po.SysMonitorFileRecord;
import com.sz.admin.system.service.FileMonitorNotificationService;
import com.sz.core.common.entity.SocketMessage;
import com.sz.core.common.entity.TransferMessage;
import com.sz.core.common.enums.SocketChannelEnum;
import com.sz.redis.WebsocketRedisService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件监控实时通知服务实现类
 *
 * @author sz-admin
 * @since 2025-01-13
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class FileMonitorNotificationServiceImpl implements FileMonitorNotificationService {

    private final WebsocketRedisService websocketRedisService;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void notifyNewImageDetected(SysMonitorFileRecord record) {
        try {
            Map<String, Object> data = new HashMap<>();
            data.put("type", "NEW_IMAGE_DETECTED");
            data.put("monitorId", record.getMonitorId());
            data.put("originalFilename", record.getOriginalFilename());
            data.put("newFilename", record.getNewFilename());
            data.put("fileUrl", record.getFileUrl());
            data.put("fileSize", record.getFileSize());
            data.put("fileType", record.getFileType());
            data.put("fileMd5", record.getFileMd5());
            data.put("processTime", formatDateTime(record.getProcessTime()));
            data.put("storagePath", record.getStoragePath());
            data.put("message", "新图片已检测到并处理完成");

            SocketMessage socketMessage = SocketMessage.builder()
                    .data(objectMapper.writeValueAsString(data))
                    .channel(SocketChannelEnum.MESSAGE)
                    .build();

            // 发送给所有在线用户
            TransferMessage transferMessage = TransferMessage.builder()
                    .message(socketMessage)
                    .toPushAll(true)
                    .build();
            websocketRedisService.sendServiceToWs(transferMessage);
            
            log.info("已发送新图片检测通知: {}", record.getOriginalFilename());
        } catch (Exception e) {
            log.error("发送新图片检测通知失败: {}", e.getMessage(), e);
        }
    }

    @Override
    public void notifyDuplicateImageSkipped(String filename, String md5Hash) {
        try {
            Map<String, Object> data = new HashMap<>();
            data.put("type", "DUPLICATE_IMAGE_SKIPPED");
            data.put("filename", filename);
            data.put("md5Hash", md5Hash);
            data.put("timestamp", formatDateTime(LocalDateTime.now()));
            data.put("message", "检测到重复图片，已跳过处理");

            SocketMessage socketMessage = SocketMessage.builder()
                    .data(objectMapper.writeValueAsString(data))
                    .channel(SocketChannelEnum.MESSAGE)
                    .build();

            TransferMessage transferMessage = TransferMessage.builder()
                    .message(socketMessage)
                    .toPushAll(true)
                    .build();
            websocketRedisService.sendServiceToWs(transferMessage);
            
            log.debug("已发送重复图片跳过通知: {}", filename);
        } catch (Exception e) {
            log.error("发送重复图片跳过通知失败: {}", e.getMessage(), e);
        }
    }

    @Override
    public void notifyFileProcessError(String filename, String errorMessage) {
        try {
            Map<String, Object> data = new HashMap<>();
            data.put("type", "FILE_PROCESS_ERROR");
            data.put("filename", filename);
            data.put("errorMessage", errorMessage);
            data.put("timestamp", formatDateTime(LocalDateTime.now()));
            data.put("message", "文件处理失败: " + errorMessage);

            SocketMessage socketMessage = SocketMessage.builder()
                    .data(objectMapper.writeValueAsString(data))
                    .channel(SocketChannelEnum.MESSAGE)
                    .build();

            TransferMessage transferMessage = TransferMessage.builder()
                    .message(socketMessage)
                    .toPushAll(true)
                    .build();
            websocketRedisService.sendServiceToWs(transferMessage);
            
            log.info("已发送文件处理错误通知: {} - {}", filename, errorMessage);
        } catch (Exception e) {
            log.error("发送文件处理错误通知失败: {}", e.getMessage(), e);
        }
    }

    @Override
    public void notifyMonitorStatusChange(Long monitorId, String status, String message) {
        try {
            Map<String, Object> data = new HashMap<>();
            data.put("type", "MONITOR_STATUS_CHANGE");
            data.put("monitorId", monitorId);
            data.put("status", status);
            data.put("message", message);
            data.put("timestamp", formatDateTime(LocalDateTime.now()));

            SocketMessage socketMessage = SocketMessage.builder()
                    .data(objectMapper.writeValueAsString(data))
                    .channel(SocketChannelEnum.MESSAGE)
                    .build();

            TransferMessage transferMessage = TransferMessage.builder()
                    .message(socketMessage)
                    .toPushAll(true)
                    .build();
            websocketRedisService.sendServiceToWs(transferMessage);
            
            log.info("已发送监控状态变更通知: monitorId={}, status={}, message={}", monitorId, status, message);
        } catch (Exception e) {
            log.error("发送监控状态变更通知失败: {}", e.getMessage(), e);
        }
    }

    @Override
    public void notifyMonitorStatistics(Long monitorId, long totalFiles, long successFiles, long errorFiles) {
        try {
            Map<String, Object> data = new HashMap<>();
            data.put("type", "MONITOR_STATISTICS");
            data.put("monitorId", monitorId);
            data.put("totalFiles", totalFiles);
            data.put("successFiles", successFiles);
            data.put("errorFiles", errorFiles);
            data.put("successRate", totalFiles > 0 ? (double) successFiles / totalFiles * 100 : 0);
            data.put("timestamp", formatDateTime(LocalDateTime.now()));
            data.put("message", String.format("监控统计: 总计%d个文件，成功%d个，失败%d个", totalFiles, successFiles, errorFiles));

            SocketMessage socketMessage = SocketMessage.builder()
                    .data(objectMapper.writeValueAsString(data))
                    .channel(SocketChannelEnum.MESSAGE)
                    .build();

            TransferMessage transferMessage = TransferMessage.builder()
                    .message(socketMessage)
                    .toPushAll(true)
                    .build();
            websocketRedisService.sendServiceToWs(transferMessage);
            
            log.debug("已发送监控统计信息通知: monitorId={}", monitorId);
        } catch (Exception e) {
            log.error("发送监控统计信息通知失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 格式化日期时间
     */
    private String formatDateTime(LocalDateTime dateTime) {
        if (dateTime == null) {
            return null;
        }
        return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}